package clustersimulator;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import net.sf.javaml.core.DenseInstance;
import java.util.ArrayList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class NetworkProcessorTest {

	ProcessingCluster[] clusters;
	ArrayList<Job> fJobs;
	NetworkProcessor np;
	Queue<Job> jobQueue;
	long clock;

	@Before
	public void setUp() throws Exception {
		clusters = new ProcessingCluster[5];
		fJobs = new ArrayList<Job>(128);
		DenseInstance centroid = new DenseInstance(new double[] {0.0, 0.0});
		clusters[0] = new ProcessingCluster(7, centroid, fJobs);
		clusters[1] = new ProcessingCluster(3, centroid, fJobs);
		clusters[2] = new ProcessingCluster(5, centroid, fJobs);
		clusters[3] = new ProcessingCluster(9, centroid, fJobs);
		clusters[4] = new ProcessingCluster(5, centroid, fJobs);
		np = new NetworkProcessor(clusters);
		jobQueue = new ArrayBlockingQueue<Job>(128);
		clock = 0;
		jobQueue.offer(new Job(1,5,1,clock));
		jobQueue.offer(new Job(2,3,3,clock));
		jobQueue.offer(new Job(3,6,4,clock));
		jobQueue.offer(new Job(4,8,3,clock));
	}

	@Test
	public void testNetworkProcessor() {
		assertTrue(np.processingClusters[0].size() == 3);
		assertTrue(np.processingClusters[1].size() == 5);
		assertTrue(np.processingClusters[2].size() == 5);
		assertTrue(np.processingClusters[3].size() == 7);
		assertTrue(np.processingClusters[4].size() == 9);
	}

	@Test
	public void testAssignJobs() {
		np.assignJobs(jobQueue, 0);

		assertFalse(np.processingClusters[0].isAvailable());
		assertTrue(np.processingClusters[0].currentJob.getJobID() == 2);

		assertFalse(np.processingClusters[1].isAvailable());
		assertTrue(np.processingClusters[1].currentJob.getJobID() == 1);

		assertTrue(np.processingClusters[2].isAvailable());

		assertFalse(np.processingClusters[3].isAvailable());
		assertTrue(np.processingClusters[3].currentJob.getJobID() == 3);

		assertFalse(np.processingClusters[4].isAvailable());
		assertTrue(np.processingClusters[4].currentJob.getJobID() == 4);
	}

	@Test
	public void testProcessJobs() {
		np.assignJobs(jobQueue, 0);
		np.processJobs(clock);
		clock++;
		assertFalse(np.processingClusters[0].isAvailable());
		assertTrue(np.processingClusters[1].isAvailable());
		assertTrue(np.processingClusters[2].isAvailable());
		assertFalse(np.processingClusters[3].isAvailable());
		assertFalse(np.processingClusters[4].isAvailable());
		np.processJobs(clock);
		clock++;
		np.processJobs(clock);
		clock++;
		assertTrue(np.processingClusters[0].isAvailable());
		assertTrue(np.processingClusters[1].isAvailable());
		assertTrue(np.processingClusters[2].isAvailable());
		assertFalse(np.processingClusters[3].isAvailable());
		assertTrue(np.processingClusters[4].isAvailable());
		np.processJobs(clock);
		clock++;
		assertTrue(np.processingClusters[0].isAvailable());
		assertTrue(np.processingClusters[1].isAvailable());
		assertTrue(np.processingClusters[2].isAvailable());
		assertTrue(np.processingClusters[3].isAvailable());
		assertTrue(np.processingClusters[4].isAvailable());
	}

	@Test
	public void testTotalIdleNodeCycles() {
		np.assignJobs(jobQueue, 0);
		for (int i=0; i < 4; i++) {
			np.processJobs(clock);
			clock++;
		}
		assertTrue(np.totalIdleNodeCycles() == 54);
	}

}
